#include "qelib.h"
#include "libfdt.h"
#include "qe_sdhci.h"



QELOG_DOMAIN("psu-sdhci");



typedef struct
{
    qe_sdhci_host host;
    qe_uint f_max;
    qe_uint f_min;
    qe_mmc_config cfg;
} psu_sdhci_dev;



static const qe_sdhci_ops psu_sdhci_ops = {
};



static qe_ret psu_sdhci_probe(const void *fdt, int offset)
{
    int len;
    const char *name;
    const qe_u32 *prop_reg;
    const qe_u32 *prop_clk;
    qe_sdhci_host *host;
    psu_sdhci_dev *dev;

    qelog_domain_set_level("mmc", QELOG_DEBUG);
    qelog_domain_set_level("sdhci", QELOG_DEBUG);

    name = fdt_get_name(fdt, offset, QE_NULL);

    prop_reg = (const qe_u32 *)fdt_getprop(fdt, offset, "reg", &len);
    if (!prop_reg) {
        qe_error("%s no reg prop", name);
        return qe_err_param;
    }

    prop_clk = (const qe_u32 *)fdt_getprop(fdt, offset, "clk", &len);
    if (!prop_clk) {
    	qe_error("%s no clk prop", name);
    	return qe_err_param;
    }

    dev = qe_malloc(sizeof(psu_sdhci_dev));
    qe_assert(dev);
    qe_memset(dev, 0, sizeof(psu_sdhci_dev));

    host = &dev->host;
    qe_notice("host %p", host);

    host->ioaddr = (qe_ubase)fdt32_to_cpu(*prop_reg);

    host->max_clk = 187498123;
    dev->f_max = host->max_clk;
    dev->f_min = 400000;

    dev->host.ops = &psu_sdhci_ops;

    qe_sdhci_setup_cfg(&dev->host, &dev->cfg, dev->f_max, dev->f_min);

    qe_sdhci_probe(&dev->host, name, &psu_sdhci_ops, dev);

    return qe_ok;
}

static const qe_device_id psu_sdhci_ids[] = {
    {.compatible="xlnx,zynqmp-sdhci"},
    {}
};

QE_DRIVER(zynqmp_sdhci) = {
   .name = "zynqmp-sdhci",
   .of_match = psu_sdhci_ids,
   .probe = psu_sdhci_probe,
};
